package com.tl.commonlibrary.tool;

import android.text.SpannableString;
import android.text.TextUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DecimalFormat;

/**
 * 数值格式化类
 * 比如：获取带符号的数值，获取保留多少小数位的值，获取带百分号的值
 * <p>
 * 参数：{@link #number} 数值部分
 * {@link #unit} 单位部分
 * (number = 20000,unit="") 等价于 (number = 2,unit="万");
 * <p>
 * formatDot:默认格式化后的数值带逗号，如果不需要可通过{@link #setFormatDot(boolean)}方法处理
 * <p>
 * Created by JongSung on 16/12/20.
 */

public class NumberUnit implements Serializable {
    public static final double UNIT_THOUSAND = 1000;//千
    public static final double UNIT_WAN = UNIT_THOUSAND * 10;//万
    public static final double UNIT_MILLION = UNIT_THOUSAND * UNIT_THOUSAND;//百万
    public static final double UNIT_YI = UNIT_WAN * UNIT_WAN;//亿
    public static final double UNIT_BILLION = UNIT_MILLION * UNIT_THOUSAND;//十亿
    public static final double UNIT_TRILLION = UNIT_BILLION * UNIT_THOUSAND;//万亿
    public static final int DEFAULT_KEEP_DECIMAL = 2;//数值默认保留位数
    public static final int KEEP_DECIMAL_DYNAMIC = -1;//于源数值小数位保留一致

    private BigDecimal number = new BigDecimal(0);
    //不需要带单位时，可以默认为空
    private String unit = "";

    private boolean formatDot = true;
    private String numberStr;

    public NumberUnit() {
        formatDot = true;
    }

    public NumberUnit(String number) {
        this(new BigDecimal(number));
    }

    public NumberUnit(double number) {
        this(new BigDecimal(number));
    }

    public NumberUnit(BigDecimal number) {
        this.number = number;
        formatDot = true;
    }

    public NumberUnit(String number, String unit) {
        this(new BigDecimal(number), unit);
    }

    public NumberUnit(BigDecimal number, String unit) {
        this.number = number;
        this.unit = unit;
        formatDot = true;
    }

    public NumberUnit setFormatDot(boolean formatDot) {
        this.formatDot = formatDot;
        return this;
    }

    public NumberUnit minus(String minusValue) {
        return new NumberUnit(this.number.subtract(new BigDecimal(minusValue)));
    }
    public NumberUnit minus(double minusValue) {
        return new NumberUnit(this.number.subtract(new BigDecimal(minusValue)));
    }
    public void set(String number) {
        set(new BigDecimal(number));
    }

    public void set(double number) {
        set(new BigDecimal(number));
    }

    public void set(BigDecimal number) {
        this.number = number;
        this.unit = "";
    }

    public void set(String number, String unit) {
        set(new BigDecimal(number), unit);
    }

    public void set(BigDecimal number, String unit) {
        this.number = number;
        this.unit = unit;
    }

    public BigDecimal getBigDecimalNumber() {
        return number;
    }

    /**
     * @return 字符串形数值
     */
    public String getNumberUnit() {
        return getNumber() + getUnit();
    }

    public Object getNumber() {
        int keepDecimal = StringUtil.getFractionCount(number.toPlainString());
        DecimalFormat df = getFormat(keepDecimal);
        return df.format(number);
    }

    public String getUnit() {
        return unit;
    }

    /**
     * 保留N位小数，{@link #number}小数位少于keepDecimal时，自动补位
     *
     * @param keepDecimal 赋值为{@link #KEEP_DECIMAL_DYNAMIC}时，需要先设置String类型的number
     * @return 字符串形数值
     */
    public String getNF(int keepDecimal) {
        return getNumberNF(keepDecimal) + getUnit();
    }

    public String getNumberNF(int keepDecimal) {
        DecimalFormat df = getFormat(keepDecimal);
        StringBuilder sb = new StringBuilder(df.format(number));
        if (sb.toString().indexOf(".") > 0) {
            //正则表达
            sb.replace(0, sb.length(), sb.toString().replaceAll("0+?$", ""));//去掉后面无用的零
            sb.replace(0, sb.length(), sb.toString().replaceAll("[.]$", ""));//如小数点后面全是零则去掉小数点
        }
        return sb.toString();
    }

    /**
     * 获取double类型的数值，保留{#keepDecimal}位小数
     *
     * @param keepDecimal
     * @return
     */
    public double getDoubleNumberNF(int keepDecimal) {
        String number = getNumberNF(keepDecimal);
        return Double.parseDouble(number);
    }

    public String get2F() {
        return getNF(2);
    }

    private DecimalFormat getFormat(int keepDecimal) {
        StringBuilder decimal = new StringBuilder("");
        if (formatDot) {
            decimal.append("##,##0");
        } else {
            decimal.append("#0");
        }
        if (keepDecimal == KEEP_DECIMAL_DYNAMIC) {
            keepDecimal = StringUtil.getFractionCount(number.toPlainString());
        }
        if (keepDecimal > 0) {
            decimal.append(".");
            for (int i = 0; i < keepDecimal; i++) {
                decimal.append(0);
            }
        }
        DecimalFormat df = new DecimalFormat(decimal.toString());
        return df;
    }

    /**
     * 保留N位小数，带正负号的数值
     *
     * @return 字符串形数值
     */
    public String getNFSigns(int keepDecimal) {
        String numberNf = getNF(keepDecimal);
        if (number.doubleValue() > 0) {
            return "+" + numberNf;
        } else {
            return numberNf;
        }
    }

    public String get2FSigns() {
        return getNFSigns(2);
    }

    /**
     * 非线程安全
     * <p>
     * 保留N位小数，带正负号的数值，带百分号
     *
     * @return
     */
    public String getNFSignsPercent(int keepDecimal) {
        number = number.multiply(new BigDecimal(100));
        String result = getNFSigns(keepDecimal) + "%";
        number = number.divide(new BigDecimal(100));
        return result;
    }

    /**
     * 非线程安全
     * <p>
     * 保留2位小数，带正负号的数值，带百分号
     *
     * @return
     */
    public String get2FSignsPercent() {
        return getNFSignsPercent(2);
    }

    /**
     * 非线程安全
     * <p>
     * 保留N位小数，带百分号
     *
     * @return
     */
    public String getNFPercent(int keepDecimal) {
        number = number.multiply(new BigDecimal(100));
        String result = getNF(keepDecimal) + "%";
        number = number.divide(new BigDecimal(100));
        return result;
    }

    /**
     * 非线程安全
     * <p>
     * 保留2位小数，带百分号
     *
     * @return
     */
    public String get2FPercent() {
        return getNFPercent(2);
    }

    public String getSigns() {
        if (number.doubleValue() > 0) {
            return "+" + number.toPlainString();
        } else {
            return number.toPlainString();
        }
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("[" + super.toString() + "] : " + "[ number = " + getNumber() + " ; ")
                .append("unit = " + getUnit() + " ; ")
                .append("numberUnit = " + getNumberUnit() + " ; ")
                .append("2f = " + get2F() + " ; ")
                .append("3f = " + getNF(3) + " ; ")
                .append("5f = " + getNF(5) + " ; ")
                .append("10f = " + getNF(10) + " ; ")
                .append("signValue = " + getSigns() + " ; ")
                .append("2FPercent = " + get2FPercent() + " ; ")
                .append("0FPercent = " + getNFPercent(0) + " ; ")
                .append("5FPercent = " + getNFPercent(5) + " ; ")
                .append("2FSigns = " + get2FSigns() + " ; ")
                .append("2FSignsPercent = " + get2FSignsPercent() + " ; ")
                .append("5FSignsPercent = " + getNFSignsPercent(5) + " ; ]");
        return builder.toString();
    }

    /**
     * 检测是否含有单位
     *
     * @return true 有单位
     */
    public boolean checkHasUnit() {
        return !TextUtils.isEmpty(unit);
    }

}
